#ifndef OPENTISSUEINSTANCE_H
#define OPENTISSUEINSTANCE_H

#include <OpenTissue/core/math/math_basic_types.h>
#include <OpenTissue/core/containers/mesh/mesh.h>
#include <OpenTissue/core/containers/grid/grid.h>
#include <OpenTissue/collision/sdf/sdf.h>
#include <OpenTissueCommand.h>
#include <OpenThreads/Thread>
typedef OpenTissue::math::BasicMathTypes<double, size_t>  math_types;
typedef math_types::real_type                             real_type;
typedef math_types::vector3_type                          vector3_type;
typedef math_types::coordsys_type                         coordsys_type;
typedef OpenTissue::polymesh::PolyMesh<math_types>        mesh_type;
typedef OpenTissue::grid::Grid<float,math_types>                 grid_type;
typedef OpenTissue::sdf::Geometry<mesh_type,grid_type>     sdf_geometry_type;

class OpenTissueInstance
{
    struct CollisionObjWrapper
    {
        void* collisionObj;
        mesh_type mesh;
        sdf_geometry_type sdfGeom;
    };

public:

    ~OpenTissueInstance();
    static OpenTissueInstance* instance();

    void convertCollisionObjToMeshType(std::string obj_file_name, void* collisionObjPtr);
    void pushCommandConvert(    std::string obj_file_name, void* collisionObjPtr);
    void pushCommandCollision(    void* collisionObjPtr1, void* collisionObjPtr2);
    void handleConvertCommand();
    void handleCollisionCommand();

    void updateByThread();

    void startThread();
private:
    OpenTissueInstance();
    static OpenTissueInstance* _instance;
    std::map<void*, CollisionObjWrapper> m_collisionObjWrapperVector;
    std::vector<CommandConvertToMeshType> m_commandConvertVector;
    std::vector<CommandConvertToMeshType> m_commandConvertVector_Cache;
    std::vector<CommandComputeCollision> m_commandCollisionVector;
    OpenThreads::Thread* m_thread;
};

#endif // OPENTISSUEINSTANCE_H
